# -*- coding: utf-8 -*-
#!/usr/bin/env python
# @Time                 : 2018/7/16
# @Modify               : 2019/4/22
# @Author               : Zhihong Tang
# @Function             : 基于TF-IDF的试验
# @Version              : python 3.6.4
from sklearn.feature_extraction.text import TfidfVectorizer

corpus = ['This is the first document.',
      'This is the second second document.',
      'And the third one.',
      'Is this the first document?',
      'No',]

vectorizer = TfidfVectorizer(min_df=1)
sparse_matrix = vectorizer.fit_transform(corpus)
terms = vectorizer.get_feature_names()

print(u"\n语料库中的词集")
print(terms)                        # 语料库中的词集
print(u"词集位置字典")
print(vectorizer.vocabulary_)
print(u"输出'document'在词集中的位置")
print(vectorizer.vocabulary_.get('document'))   # 输出'document'在词集中的位置

print(u"\n对一句新句子进行Hence转换")
print(vectorizer.transform(['Something completely new.']).toarray())
print(vectorizer.transform(['This is a new document.']).toarray())

print(u"\nTfidf向量表示")
print(sparse_matrix)                # 向量表示
print(u"\nTfidf矩阵表示")
print(sparse_matrix.toarray())      # 矩阵表示


'''
最终的结果是一个 5×10 矩阵。
每行表示一个文档，每列表示该文档中的每个词的评分。
如果某个词没有出现在该文档中，则相应位置就为 0 。
数字 10 表示语料库里共有 5 个（不同的）文档。
数字 10 表示语料库里词汇表中一共有 10 个（不同的）词。
例如：
    你可以看到在文档1中，并没有出现 and，所以矩阵第一行第一列的值为 0 。
    单词 first 只在文档1中出现过，所以第一行中 first 这个词的权重较高。
    单词 no 只在文档5中出现过，且是文档5中唯一的一个词，所以 第五行第五列的值为1。
    而 document 和 this 在 3 个文档中出现过，所以它们的权重较低。
    而 the 在 4 个文档中出现过，所以它的权重最低。
'''

'''
输出结果：
语料库中的词集
['and', 'document', 'first', 'is', 'no', 'one', 'second', 'the', 'third', 'this']
词集位置字典
{u'and': 0, u'third': 8, u'no': 4, u'this': 9, u'is': 3, u'one': 5, u'second': 6, u'the': 7, u'document': 1, u'first': 2}
输出'document'在词集中的位置
1

对一句新句子进行Hence转换
[[ 0.   0.  0.  0.  0.  0.  0.  0.  0.  0.]]
[[ 0.   0.57735027  0.  0.57735027  0.  0.  0.  0.  0.  0.57735027]]

Tfidf向量表示
  (0, 9)	0.44027050419943065
  (0, 3)	0.44027050419943065
  (0, 7)	0.3703694278374568
  (0, 2)	0.5303886653382521
  (0, 1)	0.44027050419943065
  (1, 9)	0.2814276978536842
  (1, 3)	0.2814276978536842
  (1, 7)	0.23674585155599548
  (1, 1)	0.2814276978536842
  (1, 6)	0.840444379131274
  (2, 7)	0.30931749359185684
  (2, 0)	0.5490363340004775
  (2, 8)	0.5490363340004775
  (2, 5)	0.5490363340004775
  (3, 9)	0.44027050419943065
  (3, 3)	0.44027050419943065
  (3, 7)	0.3703694278374568
  (3, 2)	0.5303886653382521
  (3, 1)	0.44027050419943065
  (4, 4)	1.0
  
Tfidf矩阵表示
[[0.         0.4402705  0.53038867 0.4402705  0.         0.         0.         0.37036943 0.         0.4402705 ]
 [0.         0.2814277  0.         0.2814277  0.         0.         0.84044438 0.23674585 0.         0.2814277 ]
 [0.54903633 0.         0.         0.         0.         0.54903633 0.         0.30931749 0.54903633 0.        ]
 [0.         0.4402705  0.53038867 0.4402705  0.         0.         0.         0.37036943 0.         0.4402705 ]
 [0.         0.         0.         0.         1.         0.         0.         0.         0.         0.        ]]
 
'''

print(u"\n文档关键词提取")
print(u'第一篇文档：This is the first document.')
a = sparse_matrix.toarray()[0]
print(u'第一篇文档的tfidf向量：',a)
b = list(a.argsort()[-3:])          # 找数组中最大的3个值的索引（从小到大）,并将数组转化为列表
b.reverse()                         # 列表顺序倒排
print(u'tfidf值最大的3个词的索引（从大到小）：',b)
for i in b:
      print terms[i]


'''
输出结果：
文档关键词提取
第一篇文档：This is the first document.
第一篇文档的tfidf向量： [ 0.          0.4402705   0.53038867  0.4402705   0.          0.          0.
  0.37036943  0.          0.4402705 ]
tfidf值最大的3个词的索引（从大到小）： [2, 9, 3]
first
this
is

'''


# TfidfVectorizer 经常会和CountVectorizer一起使用
print(u"\n\nTfidfVectorizer 经常会和CountVectorizer一起使用")
print(u"CountVectorizer介绍")
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(u"语料库中的词集")
print(vectorizer.get_feature_names())
print(u"按文档词频统计")
print(X.toarray())
print(u"整个语料库词频统计")
print(X.toarray().sum(axis=0))

'''
输出结果：
TfidfVectorizer 经常会和CountVectorizer一起使用
CountVectorizer介绍
语料库中的词集
[u'and', u'document', u'first', u'is', u'no', u'one', u'second', u'the', u'third', u'this']
按文档词频统计
[[0 1 1 1 0 0 0 1 0 1]
 [0 1 0 1 0 0 2 1 0 1]
 [1 0 0 0 0 1 0 1 1 0]
 [0 1 1 1 0 0 0 1 0 1]
 [0 0 0 0 1 0 0 0 0 0]]
整个语料库词频统计
[1 3 2 3 1 1 2 4 1 3]

'''